﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using FCTIP20.ViewModel;
using System.Xml.Linq;

namespace FCTIP20.Procdure
{

    // 定义TCP客户端类
    public class Tcp_Client
    {
        //声明
        public event EventHandler<EventArgs> MsgLog;
        public event EventHandler<EventArgs> resultMsg;
        // 客户端Socket对象，用于与服务器建立TCP连接
        Socket clientSocket;
        // 服务器的IP地址
        string _IP;
        // 服务器的端口
        int _Port;
        // 服务器的IPAddress对象
        IPAddress _ipAddress;
        // 服务器的IPEndPoint对象，包含IP地址和端口
        IPEndPoint _iPEndPoint;
        // 标识连接状态
        bool linked = false;
        // 标识是否曾经断开连接
        bool unlinked = false;
        int tryConnectionCount = 0;

        // 构造函数，初始化IP地址和端口
        public Tcp_Client(string ip, int port)
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 创建TCP连接的Socket对象
            _IP = ip; // 设置IP地址
            _Port = port; // 设置端口号
            _ipAddress = IPAddress.Parse(ip); // 将字符串IP地址解析为IPAddress对象
            _iPEndPoint = new IPEndPoint(_ipAddress, port); // 创建端点对象，包含IP地址和端口
        }

        // 当前连接状态
        private bool _Connected;
        public bool Connected
        {
            get { return _Connected = clientSocket.Connected; } // 返回Socket的连接状态
        }
        // 连接到服务器
        public bool ConnectServer()
        {
            try
            {
                if (!linked)
                { // 如果没有连接
                    if (unlinked)
                    {
                        // 如果曾经断开连接，重新创建Socket
                        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    }
                    // 连接到服务器
                    clientSocket.Connect(_iPEndPoint);
                    if (clientSocket.Connected)
                    { // 如果连接成功
                        linked = true; // 设置连接状态为已连接
                        MsgLog?.Invoke(string.Format("{0}-连接成功", "镭雕机"), null);
                        ReceiveData(); // 调用方法开始接收数据
                        tryConnectionCount = 0;
                        return true;
                    }
                    else
                    { 
                        // 如果连接失败
                        MsgLog?.Invoke(string.Format("{0}-连接失败", "镭雕机"), null);
                        MsgLog?.Invoke(string.Format($"{0}-镭雕机重新连接-第{tryConnectionCount}次重连...!", "镭雕机"), null);
                        Thread.Sleep(30000);
                        ConnectServer();
                        tryConnectionCount++;
                       // return false;
                    }
                }
                else
                { // 如果已经连接
                    MsgLog?.Invoke(string.Format("{0}-连接成功", "镭雕机"), null);
                   //msg = $"[Info] 已连接";
                    tryConnectionCount = 0;
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                MsgLog?.Invoke(string.Format("{0}-连接失败", "镭雕机无法连接!"), null);
                return false;
            }
        }

        // 断开与服务器的连接
        public bool DisConnectServer()
        {
            try
            {
                if (linked)
                { // 如果已连接
                    linked = false; // 设置连接状态为未连接
                    clientSocket.Disconnect(false); // 断开连接并释放资源
                    unlinked = true; // 标记为已断开
                    MsgLog?.Invoke(string.Format("{0}-连接断开", "客户端连接断开!"), null);
                    return true;
                }
                else
                { // 如果已经是断开状态
                    MsgLog?.Invoke(string.Format("{0}-连接断开", "客户端连接已断开!"), null);
                    return true;
                }
            }
            catch (Exception ex)
            {
                MsgLog?.Invoke(string.Format("{0}-断开失败", $"信息={ex}!"), null);
                return false;
            }
        }

        // 向服务器发送消息
        public bool SendToServer(string cmd)
        {
            try
            {
                if (clientSocket.Connected)
                { // 如果已连接
                    clientSocket.Send(Encoding.UTF8.GetBytes(cmd)); // 将命令转换为字节并发送
                    MsgLog?.Invoke(string.Format("{0}-发送", $"信息={cmd}"), null);
                    return true;
                }
                else
                { // 如果未连接
                    MsgLog?.Invoke(string.Format("{0}-连接失败", "镭雕机未连接!"), null);
                    return false;
                }
            }
            catch (Exception ex)
            {
                MsgLog?.Invoke(string.Format("{0}-发送信息失败", $"信息={ex}!"), null);
                return false;
            }
        }

        // 接收来自服务器的数据
        private void ReceiveData()
        {
            string str = ""; // 存储接收到的消息
            Task.Run(() => {
                while (linked)
                { // 只要连接保持有效，就持续接收数据
                    try
                    {
                        if (clientSocket.Connected)
                        {
                            Thread.Sleep(10); // 为了避免占用过多的CPU时间，稍微暂停一下
                        }
                        else
                        {
                            continue; // 如果连接断开，继续检查连接状态
                        }
                        byte[] data = new byte[1024]; // 缓冲区用于接收数据
                        int length = clientSocket.Receive(data); // 接收服务器发送的数据
                        string message = Encoding.UTF8.GetString(data, 0, length); // 将接收到的字节数据转换为字符串
                        if (message != "")
                        {
                            str = message; // 存储接收到的消息
                            resultMsg?.Invoke(string.Format("{0}-返回信息", message), null);
                        }
                    }
                    catch (Exception ex)
                    {
                        resultMsg?.Invoke(string.Format("{0}-返回错误", "发送指令出错！"), null);
                    }
                }
            });
        }
    }
}
